package com.kifas.controller;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo;
import javax.xml.bind.JAXBElement;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.kifas.entity.AkunMasterEntity;
import com.kifas.entity.BukuHutangEntity;
import com.kifas.entity.HutangEntity;
import com.kifas.entity.SupplierEntity;
import com.kifas.entity.TypeAkunEntity;
import com.kifas.model.xml.AkunMasterModel;
import com.kifas.model.xml.BukuHutangModel;
import com.kifas.model.xml.HutangModel;
import com.kifas.model.xml.PersistStatus;
import com.kifas.model.xml.SupplierModel;
import com.kifas.model.xml.TypeAkunModel;
import com.kifas.service.EntityServiceManager;

@Component
@Scope("prototype")
@Path("/Hutangs")
public class HutangController {

	private static Logger log = Logger.getLogger(HutangController.class);

	@Context
	UriInfo uriInfo;

	@Autowired
	private EntityServiceManager entityManager;

	@GET
	@Produces(MediaType.TEXT_XML)
	public List<HutangModel> getHutangs() {
		return transformList(entityManager.getHutangs());
	}
	
	@GET
	@Path("BelumLunas")
	@Produces(MediaType.TEXT_XML)
	public List<HutangModel> getHutangsBlmLns() {
		return checkLunas(transformList(entityManager.getHutangs()), false);
	}
	
	@GET
	@Path("Lunas")
	@Produces(MediaType.TEXT_XML)
	public List<HutangModel> getHutangsLns() {
		return checkLunas(transformList(entityManager.getHutangs()), true);
	}
	
	@GET
	@Path("BelumLunas/Range")
	@Produces(MediaType.TEXT_XML)
	public List<HutangModel> getHutangsBlmLns(@QueryParam("start") String start, @QueryParam("end") String end) {
		SimpleDateFormat formatter  = new SimpleDateFormat("ddMMyyyy");
		try {
			return checkLunas(transformList(entityManager.getHutangs(formatter.parse(start), formatter.parse(end))), false);
		} catch (Exception e) {
			return new ArrayList<HutangModel>();
		}
	}
	
	@GET
	@Path("Lunas/Range")
	@Produces(MediaType.TEXT_XML)
	public List<HutangModel> getHutangsLns(@QueryParam("start") String start, @QueryParam("end") String end) {
		SimpleDateFormat formatter  = new SimpleDateFormat("ddMMyyyy");
		try {
			return checkLunas(transformList(entityManager.getHutangs(formatter.parse(start), formatter.parse(end))), true);
		} catch (Exception e) {
			return new ArrayList<HutangModel>();
		}
	}

	@GET
	@Path("{id}")
	@Produces(MediaType.TEXT_XML)
	public HutangModel getHutang(@PathParam("id") Long idHutang) {
		return transform(entityManager.getHutang(idHutang));
	}

	@GET
	@Path("JatuhTempo/{days}")
	@Produces(MediaType.TEXT_XML)
	public List<HutangModel> getHutangJatuhTempo(@PathParam("days") int days) {
		return transformList(entityManager.getHutangs(days));
	}

	@GET
	@Path("JatuhTempo/BelumLunas/{days}")
	@Produces(MediaType.TEXT_XML)
	public List<HutangModel> getHutangJatuhTempoBlmLns(@PathParam("days") int days) {
		return checkLunas(transformList(entityManager.getHutangs(days)), false);
	}

	@GET
	@Path("JatuhTempo/Lunas/{days}")
	@Produces(MediaType.TEXT_XML)
	public List<HutangModel> getHutangJatuhTempoLns(@PathParam("days") int days) {
		return checkLunas(transformList(entityManager.getHutangs(days)), true);
	}

	@GET
	@Path("Supplier/{id}")
	@Produces(MediaType.TEXT_XML)
	public List<HutangModel> getHutangBySupplier(@PathParam("id") Long idSupplier) {
		SupplierEntity supplier = entityManager.getSupplier(idSupplier);
		return transformList(entityManager.getHutangs(supplier));
	}
	
	@GET
	@Path("Supplier/BelumLunas/{id}")
	@Produces(MediaType.TEXT_XML)
	public List<HutangModel> getHutangBySupplierBlmLns(@PathParam("id") Long idSupplier) {
		SupplierEntity supplier = entityManager.getSupplier(idSupplier);
		return checkLunas(transformList(entityManager.getHutangs(supplier)), false);
	}
	
	@GET
	@Path("Supplier/Lunas/{id}")
	@Produces(MediaType.TEXT_XML)
	public List<HutangModel> getHutangBySupplierLns(@PathParam("id") Long idSupplier) {
		SupplierEntity supplier = entityManager.getSupplier(idSupplier);
		return checkLunas(transformList(entityManager.getHutangs(supplier)), true);
	}

	// @PUT
	// @Consumes(MediaType.APPLICATION_XML)
	// @Produces(MediaType.APPLICATION_XML)
	// public PersistStatus update(JAXBElement<HutangModel> xml) {
	// return new PersistStatus("HutangEntity", "dropped",
	// "Update hutang entity is not implemented yet");
	// }

	@POST
	@Consumes(MediaType.APPLICATION_XML)
	@Produces(MediaType.APPLICATION_XML)
	public PersistStatus insert(JAXBElement<HutangModel> xml) {
		HutangModel model = xml.getValue();
		SupplierEntity supplier = entityManager.getSupplier(model.getSupplier().getIdSupplier());
		List<BukuHutangEntity> bukuHutangs = new ArrayList<BukuHutangEntity>();
		for (BukuHutangModel bukuHutangModel : model.getBukuHutangModels()) {
			AkunMasterEntity akunMaster = entityManager.getAkunMaster(bukuHutangModel.getAkunMaster().getKodeAkun());
			BukuHutangEntity bukuHutang = new BukuHutangEntity(null, akunMaster, bukuHutangModel.getDebet(), bukuHutangModel.getKredit(),
					bukuHutangModel.getTanggal(), bukuHutangModel.getKeterangan(), bukuHutangModel.getPosting(), bukuHutangModel.getNoFaktur(),
					bukuHutangModel.getDeskripsi(), bukuHutangModel.getSisaBayar(), bukuHutangModel.getCreatedBy(), bukuHutangModel.getCreatedDate());
			bukuHutangs.add(bukuHutang);
		}
		HutangEntity hutangEntity = new HutangEntity(null, model.getTanggal(), model.getTanggalJatuhTempo(), model.getSyaratBayar(), model.getNoFaktur(),
				supplier, model.getAmount(), model.getKeterangan(), model.getNoRef(), bukuHutangs, model.getCreatedBy(), model.getCreatedDate());
		try {
			entityManager.persist(hutangEntity);
		} catch (Exception e) {
			log.error("can not persist hutang entity", e);
			return new PersistStatus("HutangEntity", "failed", "can not persist hutang entity");
		}
		return new PersistStatus("HutangEntity", "success");
	}

	private List<HutangModel> transformList(List<HutangEntity> hutangs) {
		List<HutangModel> hutangModels = new ArrayList<HutangModel>();
		for (HutangEntity hutang : hutangs) {
			hutangModels.add(transform(hutang));
		}
		return hutangModels;
	}

	private HutangModel transform(HutangEntity hutang) {
		SupplierEntity supplierEntity = hutang.getSupplier();
		SupplierModel supplier = new SupplierModel(supplierEntity.getIdSupplier(), supplierEntity.getNamaSupplier(), supplierEntity.getAlamat(),
				supplierEntity.getNoTelp(), supplierEntity.getNoFax(), supplierEntity.getContactPerson(), supplierEntity.getCreatedBy());
		List<BukuHutangEntity> bukuHutangEntities = entityManager.getBukuHutangs(hutang);
		List<BukuHutangModel> bukuHutangModels = new ArrayList<BukuHutangModel>();
		if (bukuHutangEntities != null) {
			for (BukuHutangEntity bukuHutang : bukuHutangEntities) {
				AkunMasterEntity akunMasterEntity = bukuHutang.getAkunMaster();
				TypeAkunEntity typeAkun = akunMasterEntity.getTypeAkun();
				TypeAkunModel typeAkunModel = new TypeAkunModel(typeAkun.getIdType(), typeAkun.getNama(), typeAkun.getDeskripsi(), typeAkun.getKode(),
						typeAkun.getCreatedBy());
				AkunMasterModel akunMaster = new AkunMasterModel(akunMasterEntity.getKodeAkun(), akunMasterEntity.getNama(), akunMasterEntity.getDk(),
						akunMasterEntity.getIdParentAkun(), akunMasterEntity.isActive(), akunMasterEntity.getDeskripsi(), akunMasterEntity.getNamaPanjang(),
						typeAkunModel, akunMasterEntity.getCreatedBy());
				bukuHutangModels.add(new BukuHutangModel(bukuHutang.getIdBukuHutang(), akunMaster, bukuHutang.getDebet(), bukuHutang.getKredit(), bukuHutang
						.getTanggal(), bukuHutang.getKeterangan(), bukuHutang.getPosting(), bukuHutang.getNoFaktur(), bukuHutang.getDeskripsi(), hutang
						.getAmount(), bukuHutang.getCreatedBy(), bukuHutang.getCreatedDate()));
			}
		}
		return new HutangModel(hutang.getIdHutang(), hutang.getTanggal(), hutang.getTanggalJatuhTempo(), hutang.getSyaratBayar(), hutang.getNoFaktur(),
				supplier, hutang.getAmount(), hutang.getKeterangan(), hutang.getNoRef(), bukuHutangModels, hutang.getCreatedBy(), hutang.getCreatedDate());
	}

	private List<HutangModel> checkLunas(List<HutangModel> l, boolean isLunas) {
		log.debug("l : " + l.size());
		List<HutangModel> lResult = new ArrayList<HutangModel>();
		boolean lunas = false;
		for (HutangModel p : l) {
			lunas = false;
			for (BukuHutangModel bp : p.getBukuHutangModels()) {
				if (bp.getSisaBayar().compareTo(new BigDecimal(0)) == 0) {
					lunas = true;
				}
			}
			if (lunas == isLunas) lResult.add(p);
		}
		return lResult;
	}

}
